﻿

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Dynamic;
using System.Runtime.InteropServices;

namespace Bzure.Common.AOP
{
    /// <summary>
    /// WeavingContext is used to transfer info between weavers and target object.
    /// </summary>
    public class WeavingContext
    {        
        private DynamicMetaObjectBinder binder;

        /// <summary>
        /// Constror 
        /// </summary>
        /// <param name="target">Be weaved object.</param>
        /// <param name="binder">Dynamic object binder <see cref="DynamicMetaObjectBinder"/></param>
        /// <param name="argumentValues">To store Arguement values of calling method.</param>
        /// <param name="returnValue">To store  return value of the calling method, if it has one.</param>
        public WeavingContext(object target, DynamicMetaObjectBinder binder, object[] argumentValues=null, object returnValue=null)
        {
            this.Target = target;
            this.binder = binder;
            this.ArgumentValues = argumentValues;
            this.ReturnValue = returnValue;
        }

        /// <summary>
        /// Current calling method's arguments values
        /// </summary>
        public object[] ArgumentValues { get; set; }

        /// <summary>
        /// Current calling method's return value.
        /// </summary>
        public object ReturnValue { get; set; }

        /// <summary>
        /// Be weaved object
        /// </summary>
        public object Target { get; private set; }

        /// <summary>
        /// Only in the method call context, the <see cref="InvokeMemberBinder"/> make sense, otherwise it is null.
        /// </summary>
        public InvokeMemberBinder InvokeMemberBinder
        {
            get  { return binder as InvokeMemberBinder; }
        }

        /// <summary>
        /// No implementation for it in this version.
        /// </summary>
        public InvokeBinder InvokeBinder
        {
            get { return binder as InvokeBinder; }
        }

        /// <summary>
        /// Only in the get indexer of target object, the <see cref="GetIndexBinder"/> make sense, otherwise it is null.
        /// </summary>
        public GetIndexBinder GetIndexBinder
        {
            get { return binder as GetIndexBinder; }
        }

        /// <summary>
        /// Only in the set indexer of target object, the <see cref="SetIndexBinder"/> make sense, otherwise it is null.
        /// </summary>
        public SetIndexBinder SetIndexBinder
        {
            get { return binder as SetIndexBinder; }
        }

        /// <summary>
        /// Only in the get prperty of target object, the <see cref="GetMemberBinder"/> make sense, otherwise it is null.
        /// </summary>
        public GetMemberBinder GetMemberBinder
        {
            get { return binder as GetMemberBinder; }
        }

        /// <summary>
        /// Only in the set prperty of target object, the <see cref="SetMemberBinder"/> make sense, otherwise it is null.
        /// </summary>
        public SetMemberBinder SetMemberBinder
        {
            get { return binder as SetMemberBinder; }
        }
 
    }
}